package controlador;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.Normalizer.Form;
import java.text.ParseException;
import java.util.Date;
import java.util.List;
import java.util.Vector;

import javax.swing.table.DefaultTableModel;

import modelo.Cliente;
import modelo.Cuenta;
import modelo.Detalle_Venta;
import modelo.Empresa;
import modelo.Producto;
import modelo.Venta;

import org.hibernate.criterion.Restrictions;

import dao.imp.Base_DatosDAO;

import vista.frmGestionarVenta;

public class ControladorGestionarVenta implements ActionListener{

	private frmGestionarVenta formularioventa;
	private Cliente cliente=null;
	private Vector<Detalle_Venta> detalles;
	private static final String title = "SACFRE/Procesar Venta";
	private int mensaje_error;
	private int mensaje_information; 
	private int mensaje_question;
	private int Si;
	
	public ControladorGestionarVenta() throws ParseException{
		super();
		detalles = new Vector<Detalle_Venta>();
		formularioventa = new frmGestionarVenta();
		mensaje_error = formularioventa.getMensaje().ERROR_MESSAGE;
		mensaje_information = formularioventa.getMensaje().INFORMATION_MESSAGE;
		mensaje_question = formularioventa.getMensaje().YES_NO_OPTION;
		Si = formularioventa.getMensaje().YES_OPTION;
		this.formularioventa.setVisible(true);
		this.formularioventa.setLocationRelativeTo(null);
		this.formularioventa.AgregarEscuchadores(this);
		Limpiar_Pantalla();
	}
	
	private void Limpiar_Cliente() {
		formularioventa.getLblapellido2().setText("");
		formularioventa.getLblnombre2().setText("");
		formularioventa.getTxtnumero().setText("");
		formularioventa.getCmbidentificacion().setSelectedItem("V-");
		formularioventa.getBtbuscar().setEnabled(true);
		formularioventa.getCmbidentificacion().setEnabled(true);
		formularioventa.getTxtnumero().setEnabled(true);
		this.cliente=null;
	}

	private void Limpiar_Pantalla() throws ParseException {
		Base_DatosDAO conexion = new Base_DatosDAO();
		Empresa empresa = (Empresa)conexion.findByProperty(Empresa.class, Restrictions.eq("estatus", 'a')).get(0);
		formularioventa.getLblnumeroventa1().setText(Integer.toString(empresa.Generar_Numero_Venta()));
		formularioventa.getLblfecha1().setText(new Date().toString());
		formularioventa.getBtagregar().setEnabled(false);
		this.detalles.removeAllElements();
		formularioventa.getTbdetalleventa().LimpiarTabla();
		Limpiar_Cliente();
		Cargar_Tabla_Producto();
		Actualizar_Total();
	}

	private void Cargar_Tabla_Producto() {
		Base_DatosDAO conexion = new Base_DatosDAO();
		Empresa empresa = (Empresa)conexion.findByProperty(Empresa.class, Restrictions.eq("estatus", 'a')).get(0);
		List<Producto> productos = empresa.getProductos();
		formularioventa.getTbproductos().LimpiarTabla();
		for (int i=0;i<productos.size();i++){
			String [] nuevafila = {productos.get(i).getCodigo(),productos.get(i).getNombre(),productos.get(i).getUnidad().getNombre()};
			formularioventa.getTbproductos().AgregarFila(nuevafila);
		}
	}

	@Override
	public void actionPerformed(ActionEvent e) {
		String actionCommad = e.getActionCommand();
		if(actionCommad.equals("")){
			Buscar_Cliente();
		}else if(actionCommad.equals("Cargar Producto")){
			Cargar_Producto();
		}		
		else if(actionCommad.equals("Remover Detalle")){
			try {
				Remover_Producto();
			} catch (ParseException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
		}
		else if(actionCommad.equals("Agregar Detalle")){
			try {
				Agregar_Detalle();
			} catch (ParseException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
		}
		else if(actionCommad.equals("Guardar")){
				try {
					Guardar();
				} catch (ParseException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
		}
		else if(actionCommad.equals("Cancelar")){
			try {
				Limpiar_Pantalla();
			} catch (ParseException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
		}
		else if (actionCommad.equals(" ")){
			Limpiar_Cliente();
		}
	}

	private void Cargar_Producto() {
		if (formularioventa.getTbproductos().getTabla().getSelectedRowCount()!=1){
			formularioventa.getMensaje().showMessageDialog(formularioventa, "Debe seleccionar un producto", title, mensaje_error);
		}else {
			String codigo = (String) formularioventa.getTbproductos().getTabla().getModel().getValueAt(formularioventa.getTbproductos().getTabla().getSelectedRow(), 0);
			boolean encontrado = false;
			for (int i=0;i<detalles.size();i++){
				if (codigo.equals(detalles.get(i).getProducto().getCodigo())){
					encontrado = true;
					i=detalles.size();
				}
			}
			if (!encontrado){
				Base_DatosDAO conexion = new Base_DatosDAO();
				Empresa empresa  = (Empresa)conexion.findByProperty(Empresa.class, Restrictions.eq("estatus", 'a')).get(0);
				Producto producto = empresa.Buscar_Producto(codigo);
				Cargar_Datos_Producto(producto);
			}else{
				formularioventa.getMensaje().showMessageDialog(formularioventa, "Este producto no puede ser agregado nuevamente como detalle", title, mensaje_error);
			}
		}
	}

	private void Cargar_Datos_Producto(Producto producto) {
		formularioventa.getLblproducto1().setText(producto.getNombre());
		formularioventa.getLblunidades1().setText(producto.getUnidad().getNombre());
		formularioventa.getBtagregar().setEnabled(true);
	}

	private void Buscar_Cliente() {
		if (formularioventa.getTxtnumero().getText().equals("")){
			formularioventa.getMensaje().showMessageDialog(formularioventa, "Debe indicar el numero de la identificacion del cliente", title, mensaje_error);
		}else{
			Base_DatosDAO conexion = new Base_DatosDAO();
			Empresa empresa = (Empresa)conexion.findByProperty(Empresa.class, Restrictions.eq("estatus", 'a')).get(0);
			Cliente cliente = empresa.Buscar_Cliente(formularioventa.getCmbidentificacion().getSelectedItem()+""+formularioventa.getTxtnumero().getText());
			if (cliente==null){
				formularioventa.getMensaje().showMessageDialog(formularioventa, "Cliente no encontrado", title, mensaje_error);
			}else if (cliente.getEstatus()=='e'){
				if (formularioventa.getMensaje().showConfirmDialog(formularioventa, "El cliente se encuentra inactivo, �Desea Reactivarlo?", title, mensaje_question)==this.Si){
					empresa.Reactivar_Cliente(cliente);
					this.cliente=cliente;
					Cargar_Datos_Cliente(cliente);
				}
			}else{
				this.cliente=cliente;
				Cargar_Datos_Cliente(cliente);
			}
		}
	}

	private void Cargar_Datos_Cliente(Cliente cliente) {
		formularioventa.getLblapellido2().setText(cliente.getApellido());
		formularioventa.getLblnombre2().setText(cliente.getNombre());
		formularioventa.getCmbidentificacion().setEnabled(false);
		formularioventa.getTxtnumero().setEnabled(false);
	}

	private void Remover_Producto() throws ParseException {
		if (formularioventa.getTbdetalleventa().getTabla().getSelectedRowCount()!=1){
			formularioventa.getMensaje().showMessageDialog(formularioventa, "Debe selecionar un detalle a Remover", title, mensaje_error);
		}else if (formularioventa.getMensaje().showConfirmDialog(formularioventa, "�Esta seguro de Remover este detalle?", title, mensaje_question)==this.Si){
			String codigo = (String)formularioventa.getTbdetalleventa().getTabla().getModel().getValueAt(formularioventa.getTbdetalleventa().getTabla().getSelectedRow(), 0);
			for (int i=0;i<detalles.size();i++){
				if (codigo.equals(detalles.get(i).getProducto().getCodigo())){
					detalles.remove(i);i=detalles.size();
				}
			}
			((DefaultTableModel)formularioventa.getTbdetalleventa().getTabla().getModel()).removeRow(formularioventa.getTbdetalleventa().getTabla().getSelectedRow());
			Actualizar_Total();
		}
	}

	private void Agregar_Detalle() throws ParseException {
		if (formularioventa.getTxtcantidad().getText().equals("0")){
			formularioventa.getMensaje().showMessageDialog(formularioventa, "El precion no puede ser 0", title, mensaje_error);
		}else if (formularioventa.getTxtprecio().getText().equals("")){
			formularioventa.getMensaje().showMessageDialog(formularioventa, "El precion no puede ser vacio", title, mensaje_error);
		}else if (formularioventa.getTxtcantidad().getText().equals("0")){
			formularioventa.getMensaje().showMessageDialog(formularioventa, "La cantidad no puede ser 0", title, mensaje_error);
		}else if (formularioventa.getTxtcantidad().getText().equals("")){
			formularioventa.getMensaje().showMessageDialog(formularioventa, "La cantidad no puede ser vacia", title, mensaje_error);
		}else{
			Base_DatosDAO conexion = new Base_DatosDAO();
			Empresa empresa = (Empresa)conexion.findByProperty(Empresa.class, Restrictions.eq("estatus", 'a')).get(0);
			Producto producto=null;
			List<Producto> productos = empresa.getProductos_Activos();
			for (int i=0;i<productos.size();i++){
				if (formularioventa.getLblproducto1().getText().equals(productos.get(i).getNombre())){
					producto=productos.get(i);i=productos.size();
				}
			}
			Detalle_Venta nuevodetalle = new Detalle_Venta(empresa.Generar_Numero_Venta(), producto, Double.valueOf(formularioventa.getTxtprecio().getText()), Integer.valueOf(formularioventa.getTxtcantidad().getText()));
			detalles.add(nuevodetalle);
			String [] nuevafila = {nuevodetalle.getProducto().getCodigo(),nuevodetalle.getProducto().getNombre(),String.valueOf(nuevodetalle.getCantidad_producto()),String.valueOf(nuevodetalle.getPrecio()),nuevodetalle.getProducto().getUnidad().getNombre(),String.valueOf(nuevodetalle.MontoDetalle_Venta())};
			formularioventa.getTbdetalleventa().AgregarFila(nuevafila);
			Actualizar_Total();
			Limpiar_Detalle();
		}
	}

	private void Actualizar_Total() throws ParseException {
		double total=0;
		for (int i=0;i<detalles.size();i++){
			total+=detalles.get(i).MontoDetalle_Venta();
		}
		formularioventa.getLblmonto().setText(String.valueOf(total)+" Bsf");
	}

	private void Limpiar_Detalle() {
		formularioventa.getLblproducto1().setText("");
		formularioventa.getTxtcantidad().setText("");
		formularioventa.getTxtprecio().setText("");
		formularioventa.getBtagregar().setEnabled(false);
	}

	private void Guardar() throws ParseException {
		if (cliente==null){
			formularioventa.getMensaje().showMessageDialog(formularioventa, "La venta debe tener  un cliente asociado", title, mensaje_error);
		}else if (detalles.size()==0){
			formularioventa.getMensaje().showMessageDialog(formularioventa, "La venta debe tener al menos un detalle", title, mensaje_error);
		}else if (formularioventa.getMensaje().showConfirmDialog(formularioventa, "�Esta Seguro de Registrar esta Venta", title, mensaje_question)==this.Si){
			Base_DatosDAO conexion = new Base_DatosDAO();
			Empresa empresa = (Empresa)conexion.findByProperty(Empresa.class, Restrictions.eq("estatus", 'a')).get(0);
			Date hoy = new Date();
			System.out.println("Cliente a buscar: "+cliente.getCedula_rif());
			String fecha= hoy.toLocaleString().substring(6,10)+"-"+hoy.toLocaleString().substring(3, 5);
			System.out.println("Cuenta a Buscar: "+fecha);
			List cuentas = conexion.findBySQLQuery("select * from cuenta where substr(fecha,1,7)='"+fecha+"' and cliente='"+this.cliente.getCedula_rif()+"'","cuenta_activa",Cuenta.class);
			if (cuentas.size()==0){
				Cuenta cuenta = new Cuenta(empresa.generarIdCuenta(), cliente, hoy);
				conexion.save(cuenta);
			}
			Venta venta = new Venta(empresa.Generar_Numero_Venta(), new Date(), empresa.getRif(), cliente, 'a');
			empresa.Registrar_Venta(venta, detalles);
			formularioventa.getMensaje().showMessageDialog(formularioventa, "Venta Registrada en forma Exitosa!", title, mensaje_information);
			Limpiar_Pantalla();
		}
	}

}
